const {
  is
} = require('bpmnlint-utils')/** * A rule that verifies that there are no disconnected * flow elements, i.e. elements without incoming * _or_ outgoing sequence flows */
module.exports = function() {
  const keyed = {}

  const outgoingReported = {}
  const incomingReported = {}
  function check(node, reporter) {
    if (!is(node, 'bpmn:SequenceFlow')) {
      return
    }

    const key = flowKey(node)
    if (key in keyed) {
      reporter.report(node.id, 'SequenceFlow is a duplicate')

      const sourceId = node.sourceRef.id
      const targetId = node.targetRef.id

      if (!outgoingReported[sourceId]) {
        reporter.report(sourceId, 'Duplicate outgoing sequence flows')

        outgoingReported[sourceId] = true
      }

      if (!incomingReported[targetId]) {
        reporter.report(targetId, 'Duplicate incoming sequence flows')

        incomingReported[targetId] = true
      }
    } else {
      keyed[key] = node
    }
  }

  return {
    check
  }
}

// helpers /////////////////

function flowKey(flow) {
  const conditionExpression = flow.conditionExpression

  const condition = conditionExpression ? conditionExpression.body : ''
  const source = flow.sourceRef ? flow.sourceRef.id : flow.id
  const target = flow.targetRef ? flow.targetRef.id : flow.id
  return source + '#' + target + '#' + condition
}
